package com.fiap.activities;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.text.DecimalFormat;
import java.util.LinkedList;
import java.util.List;

import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.utils.URLEncodedUtils;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;

import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Color;
import android.location.Location;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.SystemClock;
import android.util.Log;
import android.view.View;
import android.view.Window;
import android.widget.Button;
import android.widget.Chronometer;
import android.widget.TextView;
import android.widget.Toast;

import com.fiap.event.GPSEvent;
import com.fiap.functions.UserFunctions;
import com.fiap.model.Estatistica;
import com.fiap.model.User;
import com.fiap.service.Corrida;
import com.fiap.service.GPSService;
import com.fiap.service.SocialService;
import com.google.android.gms.common.GooglePlayServicesNotAvailableException;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.MapFragment;
import com.google.android.gms.maps.MapsInitializer;
import com.google.android.gms.maps.model.BitmapDescriptorFactory;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.Marker;
import com.google.android.gms.maps.model.MarkerOptions;
import com.google.android.gms.maps.model.PolylineOptions;

public class GPSActivity extends BaseActivity {
    
	// ===========================================================
	// TAG used for log
	// ===========================================================
	private static final String TAG = "GPSActivity";
	private static final String ServletUrl="http://ec2-107-21-178-180.compute-1.amazonaws.com:8080/TesteServlet/TesteServlet";
	
	private Bundle bundle;
	
	// LE
	private GoogleMap map;
	private Marker actualMarker;
	private LatLng gpsUserPosition;
	private DialogInterface.OnClickListener dialogClickListener;
	
	
	// ===========================================================
	// View fields
	// ===========================================================
	private TextView txtVelocidade;
    private TextView txtVelocidadeMaxima;
    private TextView txtVelocidadeMedia;
    private TextView txtDistancia;
	private TextView txtCalorias;
	//private TextView txtTempo;
	private Button btnIniciar;
	private Button btnConvidar;
	private Button btnPostar;
	private Chronometer chronometer;
	private Button btnParar;
	
	// ===========================================================
    // Singleton classes
	// ===========================================================
	private GPSService gpsService;
	private Corrida corrida;
	private Estatistica estatistica;
	
	// ===========================================================
    // Activity variables
	// ===========================================================
	private boolean calibrando = true;
	
	@Override
	public void onCreate(Bundle savedInstanceState) {
		requestWindowFeature(Window.FEATURE_NO_TITLE);       
		super.onCreate(savedInstanceState);
		
		SocialService.init(getApplicationContext());
		
		setContentView(R.layout.gps);
		bundle = new Bundle();
		
		gpsService = GPSService.getInstance();	
		corrida = Corrida.getInstance();
		
		map = ((MapFragment) getFragmentManager().findFragmentById(R.id.map))
		        .getMap();
		
		if (gpsService.isStarted()){
			map.setMyLocationEnabled(true);
		    map.getUiSettings().setMyLocationButtonEnabled(true);
		    map.getUiSettings().setCompassEnabled(true);
		}
		
		
	    try {
			MapsInitializer.initialize(getApplicationContext());
	    } catch (GooglePlayServicesNotAvailableException ex){
	    	//User doesn't have Google Play Services Installed. Look for the latest version for Download and install it.
	    	Toast toast = Toast.makeText(this, 
					 "Problemas durante o carregamento do mapa",				
					 Toast.LENGTH_SHORT);
			toast.show();
			backToInfo(null);
	    }
	    
		prepararTela();
		
		gpsService.setEvent(new GPSEvent() {
			public void onGPSUpdate(Location location) {
				if (gpsService.isStarted() && 
						corrida.isRunning()) {
					
					map.setMyLocationEnabled(true);
				    map.getUiSettings().setMyLocationButtonEnabled(true);
				    map.getUiSettings().setCompassEnabled(true);
					
				    double tempSpeed = Math.random() % 2 + 20;
					
					long elapsedTime = corrida.getStartElapsedTime();
					chronometer.setBase(elapsedTime);
					chronometer.start();
				    
					//LE
					gpsUserPosition = new LatLng(gpsService.getLastLocation().getLatitude(), 
							  gpsService.getLastLocation().getLongitude());
					
					corrida.addPosition(gpsUserPosition);
					
					if (actualMarker != null){
						actualMarker.remove();
					} 
//					else {
//						map.moveCamera(CameraUpdateFactory.newLatLngZoom(gpsUserPosition, 15));
//					}
					
					actualMarker = map.addMarker(new MarkerOptions().position(gpsUserPosition)
																	.title("João")
																	.snippet("Runners porra!")
																	.icon(BitmapDescriptorFactory.fromResource(R.drawable.personagem_mapa_001)));
					
					map.moveCamera(CameraUpdateFactory.newLatLngZoom(gpsUserPosition, 15));
					
					PolylineOptions rectLine = new PolylineOptions().width(3).color(Color.RED);
					for(int i = 0 ; i < corrida.getArrayPositionsRoute().size() ; i++) {          
						rectLine.add(corrida.getArrayPositionsRoute().get(i));
					}
					
					map.addPolyline(rectLine);
					//FIMLE
					
					estatistica = Estatistica.getInstance(gpsService.getLastLocation().getLatitude(), 
							  gpsService.getLastLocation().getLongitude());
					
					estatistica.update(location.getLatitude(), location.getLongitude(), location.getSpeed());
					
					txtVelocidade.setText(String.format("%.2f km/h", estatistica.getVelocidade())); //km/h
					txtVelocidadeMaxima.setText(String.format("%.2f km/h", estatistica.getVelocidadeMaxima()));//km/h
					txtVelocidadeMedia.setText(String.format("%.2f km/h", estatistica.getVelocidadeMedia())); //km/h
					txtDistancia.setText(String.format("%.2f", estatistica.getDistanciaTotal()));
					txtCalorias.setText(String.format("%.2f cal", estatistica.getCalorias()));
//					txtTempo.setText(String.format("%.2f min", estatistica.getTempoTotal()));
//					txtLocation.setText(gpsService.getLastLocation().getLatitude() + 
//										";" +
//										gpsService.getLastLocation().getLongitude()); 
				} else {
					btnIniciar.setEnabled(true);
					txtVelocidade.setText("Pronto");	
				}
			}
		});
		gpsService.onActivityCreated(this);
		corrida.onActivityCreated();
	}
	
	@Override
	protected void onStart() {
		super.onStart();
		gpsService.onActivityStarted();
		corrida.onActivityStarted();
	}
	
	@Override
	protected void onResume() {
		super.onResume();
		gpsService.onActivityResumed();
		corrida.onActivityResumed();
	}
	
	@Override
	protected void onPause() {
		super.onPause();
		gpsService.onActivityPaused();
		corrida.onActivityPaused();
	}
	
	@Override
	protected void onStop() {
		super.onStop();
		gpsService.onActivityStopped();
		corrida.onActivityStopped();
	}

	@Override
	protected void onDestroy() {
		// TODO Auto-generated method stub
		super.onDestroy();
		gpsService.onActivityDestroy();
		Log.d("Teste", "Destroying activity");
	}
	
	private void prepararTela() {
		txtDistancia		= (TextView)findViewById(R.id.text_gps_distancia);
		txtVelocidade		= (TextView)findViewById(R.id.text_gps_velocidade);
    	txtVelocidadeMaxima	= (TextView)findViewById(R.id.text_gps_velocidadeMaxima);
    	txtVelocidadeMedia	= (TextView)findViewById(R.id.text_gps_velocidadeMedia);
    	txtCalorias			= (TextView)findViewById(R.id.text_gps_calorias);
    	//txtTempo			= (TextView)findViewById(R.id.text_gps_tempo);
    	btnIniciar			= (Button)findViewById(R.id.button_gps_iniciar);
//    	btnConvidar			= (Button)findViewById(R.id.button_gps_convidar);
//    	btnPostar			= (Button)findViewById(R.id.button_gps_post);
    	chronometer 		= (Chronometer) findViewById(R.id.chronometer);
    	btnParar			= (Button)findViewById(R.id.button_stop);
    	
    	btnIniciar.setOnClickListener(new View.OnClickListener() {
			
			public void onClick(View view) {
				if (btnIniciar.getText().equals(getString(R.string.pausar))) {
					btnIniciar.setText(getString(R.string.iniciar));
					corrida.stop();
					chronometer.stop();
//					irParaTelaPostagem();
				} else {
					chronometer.setBase(SystemClock.elapsedRealtime());
					chronometer.start();
					corrida.start();
					btnIniciar.setText(getString(R.string.pausar));
				}
			}
		});
    	
    	btnParar.setOnClickListener(new View.OnClickListener() {
			
			public void onClick(View view) {
				corrida.stop();
				chronometer.stop();
				showShareDialog();
			}
		});
    	
    	
    	dialogClickListener = new DialogInterface.OnClickListener() {
    	    @Override
    	    public void onClick(DialogInterface dialog, int which) {
    	        switch (which){
    	        case DialogInterface.BUTTON_POSITIVE:
    	        	share();
    	            break;

    	        case DialogInterface.BUTTON_NEGATIVE:
    	        	backToInfo(null);
    	            break;
    	        }
    	    }
    	};
    	
    	
//    	btnPostar.setOnClickListener(new View.OnClickListener() {
//
//			public void onClick(View view) {
//				String message = "Acabei de correr " + txtDistancia.getText().toString() + 
//						"km em " + chronometer.getText().toString() + "h!";
//				UserFunctions userFunction = new UserFunctions();
//                User user = userFunction.getUser(getApplicationContext());
//                
//                userFunction.postOnRunners(user.getId(), message);
//			}
//			
//		});
//    	
//    	btnConvidar.setOnClickListener(new View.OnClickListener() {
//
//			public void onClick(View view) {
//				irParaTelaConvite();
//			}
//			
//		});
	}
	protected void share() {
		String message = "Acabei de correr " + txtDistancia.getText().toString() + 
				"km em " + chronometer.getText().toString() + "h!";
		UserFunctions userFunction = new UserFunctions();
        User user = userFunction.getUser(getApplicationContext());
        
        userFunction.postOnRunners(user.getId(), message);
		backToInfo(null);
	}

	public void showShareDialog() {
    	AlertDialog.Builder builder = new AlertDialog.Builder(this);
    	builder.setMessage("Deseja compartilhar sua corrida?").setPositiveButton("Sim", dialogClickListener)
    	    .setNegativeButton("Não", dialogClickListener).show();
	}
	
	private void irParaTelaPostagem() {
		bundle.remove(Constants.PARAM_CONVITE);
		bundle.remove(Constants.PARAM_MENASGEM);
		
		bundle.putSerializable(Constants.PARAM_CONVITE, Boolean.FALSE);
		bundle.putSerializable(Constants.PARAM_MENASGEM, 
				String.format("Acabei de percorrer %.2f km em %.2f minutos, " +
						"com uma velocidade média de %.2f km/h.",
						estatistica.getDistanciaTotal(),
						estatistica.getTempoTotal(),
						estatistica.getVelocidadeMedia()));
		
		iniciarActivity(LoginFacebookActivity.class, bundle);
	}

	private void irParaTelaConvite() {
		bundle.remove(Constants.PARAM_CONVITE);
		bundle.remove(Constants.PARAM_MENASGEM);
		
		bundle.putSerializable(Constants.PARAM_CONVITE, Boolean.TRUE);
		
		iniciarActivity(ConviteActivity.class, bundle);
	}
	
	private class SendPositionTask extends AsyncTask<String, Void, String> {
	    @Override
	    protected String doInBackground(String... params) {
	    	String response = "";
	    	String url = params[0];
	    	String latitude = params[1];
	    	String longitude = params[2];
	    	String email = params[3];
	    	Log.w(TAG, "latitude from Location: " + latitude);
	    	Log.w(TAG, "longitude from Location: " + longitude);
		        
	    	url += "?";
	    			
	        List<NameValuePair> nameValuePairs = new LinkedList<NameValuePair>();
	        nameValuePairs.add(new BasicNameValuePair("latitude", latitude));
	        nameValuePairs.add(new BasicNameValuePair("longitude", longitude));
	        nameValuePairs.add(new BasicNameValuePair("email", email));
	        
	        String paramString = URLEncodedUtils.format(nameValuePairs, "UTF-8");
	        		
	        url += paramString;
	        Log.w(TAG, "url = " + url);
	        DefaultHttpClient client = new DefaultHttpClient();
	        HttpGet httpGet = new HttpGet(url);
	        
	        
	        try {
	            HttpResponse execute = client.execute(httpGet);
	            InputStream content = execute.getEntity().getContent();

	            BufferedReader buffer = new BufferedReader(new InputStreamReader(content));
	            String s = "";
	            while ((s = buffer.readLine()) != null) {
	            	response += s;
		        }

	        } catch (Exception e) {
	          e.printStackTrace();
	        }
	      return response;
	    }

//	    @Override
//	    protected void onPostExecute(String result) {
//	    	webServiceTextView.setText(result);
//	    }
	  }
	
	public void sendPosition(Location location) {
		Log.w(TAG, "-LAT" + location.getLatitude());
		Log.w(TAG, "-LON" + location.getLongitude());
		
		DecimalFormat decimalFormatter = new DecimalFormat("0.######");

        String latitude = decimalFormatter.format(location.getLatitude());
        String longitude = decimalFormatter.format(location.getLongitude());
		Log.w(TAG, "--LAT" + latitude);
		Log.w(TAG, "--LON" + longitude);
		String email = "leandro.alsberg@gmail.com";
	    SendPositionTask task = new SendPositionTask();
	    task.execute(new String[] { ServletUrl, latitude, longitude, email });

	  }

	 public void goToMap (View v) {
		 	Intent i  = new Intent(MainActivity.ACAO_EXIBIR_SAUDACAO);
		 	i.addCategory(MainActivity.CATEGORIA_SAUDACAO);
		 	i.putExtra(MainActivity.EXTRA_POSICAO_USUARIO, gpsService.getLastLocation().getLatitude() + 
		 																							   ";" +
		 													gpsService.getLastLocation().getLongitude());
			startActivity(i);
	    }
	 
	 public void backToInfo (View v) {
		  	Intent i = new Intent(getApplicationContext(), MainMenuActivity.class);
		  	startActivity(i);
		  }
}
